home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1997 / MacHack 1997.toast / Hacks / Hacks ’97 / Warrior’s Progress / source code / Source / Libraries / BitArray / BitArrayBase.cp < prev    next >
Encoding:
Text File  |  1997-06-28  |  4.6 KB  |  237 lines  |  [TEXT/CWIE]

  1. // BitArrayBase.cp
  2.  
  3. #ifndef BitArrayBase_h
  4. #include "BitArrayBase.h"
  5. #endif
  6. #ifndef MinMax_h
  7. #include "MinMax.h"
  8. #endif
  9.  
  10. BitArrayBase::BitArrayBase( uint32 *theBits,
  11.                                      uint32 theLength )
  12.   : bits( theBits ),
  13.      length( theLength ),
  14.      units( (theLength + unitLength - 1) / unitLength ),
  15.      end( bits + (theLength + unitLength - 1) / unitLength ),
  16.      lastUnitMask( (theLength % unitLength == 0)
  17.                          ? ~0L
  18.                          : (1L << (theLength % unitLength)) - 1 )
  19.   {}
  20.     
  21. BitArrayBase::BitArrayBase( uint32 *theBits,
  22.                                      uint32 theLength,
  23.                                      bool initialValue )
  24.   : bits( theBits ),
  25.      length( theLength ),
  26.      units( (theLength + unitLength - 1) / unitLength ),
  27.      end( bits + (theLength + unitLength - 1) / unitLength ),
  28.      lastUnitMask( (theLength % unitLength == 0)
  29.                          ? ~0L
  30.                          : (1L << (theLength % unitLength)) - 1 )
  31.   {
  32.     SetAll( initialValue );
  33.     if ( initialValue )
  34.         SetAll();
  35.      else
  36.         ClearAll();
  37.   }
  38.  
  39. bool BitArrayBase::operator[]( uint32 i ) const
  40.   {
  41.     Assert( i < length );
  42.     return ( bits[ i/unitLength ] & 1L << ( i % unitLength ) ) != 0;
  43.   }
  44.  
  45. BitReference BitArrayBase::operator[]( uint32 i )
  46.   {
  47.     Assert( i < length );
  48.     return BitReference( bits[ i/unitLength ], i % unitLength );
  49.   }
  50.  
  51. void BitArrayBase::SetAll( bool value )
  52.   {
  53.     if ( value )
  54.         SetAll();
  55.      else
  56.         ClearAll();
  57.   }
  58.  
  59. void BitArrayBase::SetAll()
  60.   {
  61.     for ( Unit *p = bits; p < end; p++ )
  62.         *p = ~0L;
  63.   }
  64.  
  65. void BitArrayBase::ClearAll()
  66.   {
  67.     for ( Unit *p = bits; p < end; p++ )
  68.         *p = 0;
  69.   }
  70.  
  71. void BitArrayBase::ChangeAll()
  72.   {
  73.     for ( Unit *p = bits; p < end; p++ )
  74.         *p = ~*p;
  75.   }
  76.  
  77. void BitArrayBase::operator=( const BitArrayBase& r )
  78.   {
  79.     Assert( length == r.length );
  80.     
  81.     if ( this == &r )
  82.         return;
  83.     
  84.     Unit *p = bits;
  85.     const Unit *q = r.bits;
  86.     
  87.     while ( p < end )
  88.         *p++ = *q++;
  89.   }
  90.  
  91. void BitArrayBase::operator&=( const BitArrayBase& r )
  92.   {
  93.     Assert( length == r.length );
  94.     
  95.     if ( this == &r )
  96.         return;
  97.     
  98.     Unit *p = bits;
  99.     const Unit *q = r.bits;
  100.     
  101.     while ( p < end )
  102.         *p++ &= *q++;
  103.   }
  104.  
  105. void BitArrayBase::operator|=( const BitArrayBase& r )
  106.   {
  107.     Assert( length == r.length );
  108.     
  109.     if ( this == &r )
  110.         return;
  111.     
  112.     Unit *p = bits;
  113.     const Unit *q = r.bits;
  114.     
  115.     while ( p < end )
  116.         *p++ |= *q++;
  117.   }
  118.  
  119. void BitArrayBase::operator^=( const BitArrayBase& r )
  120.   {
  121.     Assert( length == r.length );
  122.     
  123.     if ( this == &r )
  124.       {
  125.         ClearAll();
  126.         return;
  127.       }
  128.     
  129.     Unit *p = bits;
  130.     const Unit *q = r.bits;
  131.     
  132.     while ( p < end )
  133.         *p++ ^= *q++;
  134.   }
  135.  
  136. bool BitArrayBase::operator==( const BitArrayBase& r ) const
  137.   {
  138.     Assert( length == r.length );
  139.  
  140.     if ( this == &r )
  141.         return true;
  142.     
  143.     const Unit *last = end - 1;
  144.  
  145.     Unit *p = bits;
  146.     const Unit *q = r.bits;
  147.     while ( p < last )
  148.         if ( *p++ != *q++ )
  149.             return false;
  150.     
  151.     return ( (*p ^ *q) & lastUnitMask ) != 0;
  152.   }
  153.  
  154. uint32 BitArrayBase::FirstZero( uint32 start ) const
  155.   {
  156.     Assert( start <= length );
  157.     
  158.     Unit *p = bits + start / unitLength;
  159.     if ( p >= end )
  160.         return length;
  161.     
  162.     Unit skip = ( 1L << (start % unitLength) ) - 1;
  163.     Unit firstUnit = *p | skip;
  164.     if ( firstUnit != ~0L )
  165.       {
  166.         uint32 result = (p - bits) * unitLength + FirstZero( firstUnit );
  167.         return Min( result, length );
  168.       }
  169.     
  170.     const Unit *last = end - 1;
  171.     for ( p++; p < last; p++ )
  172.         if ( *p != ~0L )
  173.             return (p - bits) * unitLength + FirstZero( *p );
  174.     
  175.     return (p - bits) * unitLength + FirstZero( *p & lastUnitMask );
  176.   }
  177.  
  178. uint32 BitArrayBase::FirstOne( uint32 start ) const
  179.   {
  180.     Assert( start <= length );
  181.     
  182.     Unit *p = bits + start / unitLength;
  183.     if ( p >= end )
  184.         return length;
  185.     
  186.     Unit skip = ( 1L << (start % unitLength) ) - 1;
  187.     Unit firstUnit = *p & ~skip;
  188.     if ( firstUnit != 0 )
  189.       {
  190.         uint32 result = (p - bits) * unitLength + FirstOne( firstUnit );
  191.         return Min( result, length );
  192.       }
  193.     
  194.     const Unit *last = end - 1;
  195.     for ( p++; p < last; p++ )
  196.         if ( *p != 0 )
  197.             return (p - bits) * unitLength + FirstOne( *p );
  198.     
  199.     return (p - bits) * unitLength + FirstOne( *p | ~lastUnitMask );
  200.   }
  201.  
  202. uint32 BitArrayBase::LastZero( uint32 start ) const
  203.   {
  204.     Assert( start <= length );
  205.     
  206.     Unit *p = bits + start / unitLength;
  207.  
  208.     Unit skip = ( 1L << (start % unitLength) ) - 1;
  209.     Unit firstUnit = *p | ~skip;
  210.     if ( firstUnit != ~0L )
  211.         return (p - bits) * unitLength + LastZero( firstUnit );
  212.  
  213.     for ( p--; p >= bits; p-- )
  214.         if ( *p != ~0L )
  215.             return (p - bits) * unitLength + LastZero( *p );
  216.     
  217.     return length;
  218.   }
  219.  
  220. uint32 BitArrayBase::LastOne( uint32 start ) const
  221.   {
  222.     Assert( start <= length );
  223.     
  224.     Unit *p = bits + start / unitLength;
  225.  
  226.     Unit skip = ( 1L << (start % unitLength) ) - 1;
  227.     Unit firstUnit = *p & skip;
  228.     if ( firstUnit != 0 )
  229.         return (p - bits) * unitLength + LastOne( firstUnit );
  230.  
  231.     for ( p--; p >= bits; p-- )
  232.         if ( *p != 0 )
  233.             return (p - bits) * unitLength + LastOne( *p );
  234.     
  235.     return length;
  236.   }
  237.